/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package trabalho.pkg3;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Victor
 */
//Nós clientes
public class Cliente extends Thread {

    private static void Download(String op, String Resposta) throws IOException, ClassNotFoundException {
        Socket socket;
        ObjectOutputStream saida;
        ObjectInputStream entrada;
        File f;
        File dir = new File("Shared");
        FileOutputStream fos;

        try {
            long inicio = System.currentTimeMillis();
            //Cria um socket com IP e porta sendo primeiro e segundo parametro
            //conexão com servidor
            socket = new Socket(Resposta.split(";")[0], 9090);
            //Crio o fluxo para a troca de dados
            saida = new ObjectOutputStream(socket.getOutputStream());
            entrada = new ObjectInputStream(socket.getInputStream());

            //Envia qual arquivo o cliente quer baixar
            saida.writeObject(op);
            saida.flush();

            if (dir.mkdir() || dir.exists()) {
                f = new File(dir, op);
                fos = new FileOutputStream(f);
                int tamanho = 4096; //buffer 4kb
                int lidos;
                byte[] buffer = new byte[tamanho];
                while ((lidos = entrada.read(buffer, 0, tamanho)) != -1) {
                    fos.write(buffer, 0, lidos);
                    fos.flush();
                }
                fos.close();
            }
            
            saida.close();
            entrada.close();
            socket.close();

            long fim = System.currentTimeMillis();

            System.out.println("Tempo de Download: " + (fim - inicio) + " milisegundos");

        } catch (IOException e) {
        }
    }

    @Override
    public void run() {
        ServerSocket servidor;
        ObjectOutputStream saida;
        ObjectInputStream entrada;
        File f;
        File dir = new File("Shared");

        while (true) {
            try {
                long inicio = System.currentTimeMillis();

                servidor = new ServerSocket(9090);
                Socket socket = servidor.accept();

                //Crio o fluxo para a troca de dados
                saida = new ObjectOutputStream(socket.getOutputStream());
                entrada = new ObjectInputStream(socket.getInputStream());

                if (dir.mkdir() || dir.exists()) {
                    f = new File(dir, (String) entrada.readObject());
                    inicio = System.currentTimeMillis();
                    FileInputStream fos = new FileInputStream(f);

                    int tamanho = 4096; //buffer 4kb
                    int lidos;
                    byte[] buffer = new byte[tamanho];
                    while (true) {
                        lidos = fos.read(buffer);
                        if (lidos == -1) {
                            break;
                        }
                        saida.write(buffer, 0, lidos);
                    }

                    fos.close();
                }

                saida.close();
                entrada.close();
                socket.close();
                servidor.close();

                long fim = System.currentTimeMillis();

                System.out.println("Tempo de Upload: " + (fim - inicio) + " milisegundos");

            } catch (IOException | ClassNotFoundException ex) {
                Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public static void listaArq(String server, int porta) {
        String[] arqs;
        File f;
        File dir = new File("Shared");
        try {
            long inicio = System.currentTimeMillis();

            if (dir.mkdir() || dir.exists()) {
                if ((arqs = dir.list()) != null) {

                    //Cria um socket com IP e porta sendo primeiro e segundo parametro
                    //conexão com servidor
                    Socket socket = new Socket(server, porta);

                    //Crio o fluxo para a troca de dados
                    ObjectOutputStream saida = new ObjectOutputStream(socket.getOutputStream());

                    saida.flush();
                    saida.writeObject("Atualizar");
                    saida.flush();
                    saida.writeObject(arqs.length);
                    saida.flush();
                    saida.writeObject(socket.getLocalAddress().getHostAddress());

                    for (int i = 0; i < arqs.length; i++) {
                        f = new File(dir, arqs[i]);
                        saida.flush();
                        saida.writeObject(f.getName());
                        saida.flush();
                        saida.writeObject(f.length());
                    }

                    saida.close();
                    socket.close();
                }
            }

            long fim = System.currentTimeMillis();
            System.out.println("Tempo de Atualização: " + (fim - inicio) + " milisegundos");

        } catch (IOException ex) {
            Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Cliente(String server, int porta) {
        this.start();
        Cliente.listaArq(server, porta);
    }

    public static void menu() {
        System.out.println("***************Menu***************");
        System.out.println("Escolha uma opcao:");
        System.out.println("1 - Adicionar");
        System.out.println("2 - Remover");
        System.out.println("3 - Download");
        System.out.println("4 - Sair");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        Socket socket;
        ObjectOutputStream saida;
        ObjectInputStream entrada;
        InputStreamReader stdin;
        BufferedReader terminal;
        String op;
        String Resposta;
        stdin = new InputStreamReader(System.in); //Inicia Buffer de leitura de teclado
        terminal = new BufferedReader(stdin);


        try {
            //Cria um socket com IP e porta sendo primeiro e segundo parametro
            if (args.length > 0) {

                //leitura teclado da opção
                menu();
                op = terminal.readLine();
                while (!op.equalsIgnoreCase("4")) {
                    //Cria um socket com IP e porta sendo primeiro e segundo parametro
                    //conexão com servidor
                    socket = new Socket(args[0], Integer.parseInt(args[1]));

                    //Crio o fluxo para o envio de dados
                    saida = new ObjectOutputStream(socket.getOutputStream());
                    entrada = new ObjectInputStream(socket.getInputStream());

                    switch (op) {
                        case "1":
                            op = "Adicionar";

                            entrada.close();
                            saida.close();
                            socket.close();
                            break;

                        case "2":
                            op = "Remover";

                            entrada.close();
                            saida.close();
                            socket.close();
                            break;

                        case "3":
                            op = "Download";
                            //envio da opção
                            saida.flush();
                            saida.writeObject(op);
                            //envia o nome do arquivo desejado
                            System.out.println("Nome do arquivo:");
                            op = terminal.readLine();
                            saida.flush();
                            saida.writeObject(op);
                            //recebe o onde o arquivo se encontra
                            Resposta = (String) entrada.readObject();
                            System.out.println("Hosts: " + Resposta);
                            //Fecha comunicação com o servidor
                            entrada.close();
                            saida.close();
                            socket.close();

                            Download(op, Resposta);

                            listaArq(args[0], Integer.parseInt(args[1]));
                            break;
                    }

                    menu();
                    op = terminal.readLine();
                }


            } else {
                //escrita.println("Insira um argumento");
            }

            System.exit(0);

            //Caso não encontre o host    
        } catch (UnknownHostException ex) {
            ex.printStackTrace();
            //Caso ocorra alguma exceção na criação do fluxo
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
